/*  This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation; either version 2.1 of the License, or (at
    your option) any later version.
    For more details, see the GNU Lesser General Public License (www.fsf.org
    or the COPYING file somewhere in the package)
 */

#ifndef OSGI_SERVICEREGISTRY_HH
#define OSGI_SERVICEREGISTRY_HH

#include "OSGi.hh"

/*! @file OSGi/ServiceRegistry.hh
    @brief Class OSGi::ServiceRegistry header.
    @author @ref Guillaume_Terrissol
    @date 19th December 2009 - 20th August 2013
    @note This file is distributed under the LGPL license.
    Refer to the file COPYING (or http://www.fsf.org) for more information.
 */

#include <map>
#include <memory>
#include <string>

#include "Service.hh"

namespace OSGi
{
//------------------------------------------------------------------------------
//                                   Services
//------------------------------------------------------------------------------

    /*! @brief Service manager.
        @version 0.6

        This class is used to hold a service collection, to be shared among the
        bundles loaded in an application.
     */
    class OSGI_EXPORT ServiceRegistry
    {
    public:
        //! @name Type
        //@{
        using Ptr = std::shared_ptr<ServiceRegistry>;                                   //!< Pointer to service manager.
        //@}
        //! @name Constructor & destructor
        //@{
                                    ServiceRegistry();                                  //!< Default constructor.
                                    ~ServiceRegistry();                                 //!< Destructor.
        //! @name Service management
        //@{
                void                checkIn(std::string pName, Service::Ptr pService);  //!< Service registering.
                void                checkOut(const std::string& pName);                 //!< Service unregistering.
                void                checkOut(Service::Ptr pService);                    //!< Service unregistering.
                Service::Ptr        findByName(const std::string& pName);               //!< Service search.
        template<class TS>
        inline  std::shared_ptr<TS> findByTypeAndName(const std::string& pName);        //!< Service search.
        //@}
        //! @name Signals
        //@{
        OSGI_DECL_SIGNAL(serviceRegistered,   Service::Ptr)                             //!< On service registered.
        OSGI_DECL_SIGNAL(serviceUnregistered, Service::Ptr)                             //!< On service unregistered.
        //@}

    private:
    
        std::map<std::string, Service::Ptr> mServices;                                  //!< Service list.
    };
}

#include "ServiceRegistry.inl"

#endif  // OSGI_SERVICEREGISTRY_HH
